module fp32_add (
    input  logic        clk,        // 时钟信号
    input  logic        rst_n,      // 复位信号（低电平有效）
    input  logic        valid_in,   // 输入数据有效
    input  logic [31:0] a_operand,  // 输入数据A
    input  logic [31:0] b_operand,  // 输入数据B
    output logic        valid_out,  // 输出数据有效
    output logic [31:0] result,     // 加法结果
    output logic        exception   // 异常标志
);

    localparam int DWIDTH = 32;  // 数据位宽 (固定为32位)
    localparam int EWIDTH = 8;  // 指数位宽 (固定为8位)
    localparam int MWIDTH = 23;  // 尾数位宽 (固定为23位)
    localparam int BIAS = 127;  // 指数偏移量 (固定为127)
    localparam int RWIDTH = 10;  // 舍入位宽度

    // 计算衍生参数
    localparam int SIGNIFICAND_WIDTH = MWIDTH + 1;  // 尾数位宽(含隐含位) = 24
    localparam int ALIGNED_WIDTH = SIGNIFICAND_WIDTH + RWIDTH;  // 对阶后尾数位宽 = 34
    localparam int GUARD_BITS = 2;  // 保护位：1bit防溢出 + 1bit符号位
    localparam int ADD_WIDTH = ALIGNED_WIDTH + GUARD_BITS + 1;  // 加法器输入位宽 = 37
    localparam int LOD_WIDTH = $clog2(ADD_WIDTH);  // LOD输出位宽 = 6

    localparam int MAX_EXP = (1 << EWIDTH) - 1;  // 最大指数值 = 255
    localparam logic [EWIDTH-1:0] EXP_ZEROS = '0;  // 全零指数
    localparam logic [EWIDTH-1:0] EXP_ONES = '1;  // 全一指数
    localparam logic [MWIDTH-1:0] MANT_ZEROS = '0;  // 全零尾数
    localparam logic [31:0] NAN = 32'h7fc00000;  // NaN值

    // IEEE 754 类型定义
    typedef struct packed {
        logic              sign;
        logic [EWIDTH-1:0] exponent;
        logic [MWIDTH-1:0] mantissa;
    } ieee754_t;

    // 特殊值检测结构
    typedef struct packed {
        logic is_inf;
        logic is_nan;
        logic is_zero;
        logic is_subnormal;
    } special_flags_t;

    // ========== 第一级流水线寄存器 (输入解析和特殊值检测) ==========
    logic valid_stage1;
    ieee754_t operand_a_s1, operand_b_s1;
    logic [EWIDTH-1:0] exp_a_s1, exp_b_s1;
    logic [SIGNIFICAND_WIDTH-1:0] mant_a_s1, mant_b_s1;
    logic sign_a_s1, sign_b_s1;
    special_flags_t flags_a_s1, flags_b_s1;

    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            valid_stage1 <= 1'b0;
            operand_a_s1 <= '0;
            operand_b_s1 <= '0;
        end else begin
            valid_stage1 <= valid_in;
            if (valid_in) begin
                operand_a_s1 <= a_operand;
                operand_b_s1 <= b_operand;
            end
        end
    end

    // 第一级组合逻辑：解析输入并检测特殊值
    always_comb begin
        // 提取IEEE 754字段
        sign_a_s1               = operand_a_s1.sign;
        sign_b_s1               = operand_b_s1.sign;
        exp_a_s1                = operand_a_s1.exponent;
        exp_b_s1                = operand_b_s1.exponent;

        // 检查特殊值
        flags_a_s1.is_inf       = (&exp_a_s1) & (~|operand_a_s1.mantissa);
        flags_a_s1.is_nan       = (&exp_a_s1) & (|operand_a_s1.mantissa);
        flags_a_s1.is_zero      = (~|exp_a_s1) & (~|operand_a_s1.mantissa);
        flags_a_s1.is_subnormal = (~|exp_a_s1) & (|operand_a_s1.mantissa);

        flags_b_s1.is_inf       = (&exp_b_s1) & (~|operand_b_s1.mantissa);
        flags_b_s1.is_nan       = (&exp_b_s1) & (|operand_b_s1.mantissa);
        flags_b_s1.is_zero      = (~|exp_b_s1) & (~|operand_b_s1.mantissa);
        flags_b_s1.is_subnormal = (~|exp_b_s1) & (|operand_b_s1.mantissa);

        // 处理隐含位：规格化数隐含位为1，非规格化数为0
        mant_a_s1               = (|exp_a_s1) ? {1'b1, operand_a_s1.mantissa} : {1'b0, operand_a_s1.mantissa};
        mant_b_s1               = (|exp_b_s1) ? {1'b1, operand_b_s1.mantissa} : {1'b0, operand_b_s1.mantissa};

        // 非规格化数的指数处理
        exp_a_s1                = (|exp_a_s1) ? operand_a_s1.exponent : 8'b1;
        exp_b_s1                = (|exp_b_s1) ? operand_b_s1.exponent : 8'b1;
    end

    // ========== 第二级流水线寄存器 (对阶处理) ==========
    logic valid_stage2;
    logic [EWIDTH-1:0] exp_a_s2, exp_b_s2, max_exponent_s2;
    logic [SIGNIFICAND_WIDTH-1:0] mant_a_s2, mant_b_s2;
    logic sign_a_s2, sign_b_s2;
    special_flags_t flags_a_s2, flags_b_s2;
    logic [EWIDTH-1:0] exp_diff_a_s2, exp_diff_b_s2;
    logic [ALIGNED_WIDTH-1:0] aligned_mant_a_s2, aligned_mant_b_s2;

    // 找到最大指数 - 第一级输出
    logic [EWIDTH-1:0] max_exponent_comb;
    assign max_exponent_comb = (exp_a_s1 > exp_b_s1) ? exp_a_s1 : exp_b_s1;

    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            valid_stage2    <= 1'b0;
            exp_a_s2        <= '0;
            exp_b_s2        <= '0;
            max_exponent_s2 <= '0;
            mant_a_s2       <= '0;
            mant_b_s2       <= '0;
            sign_a_s2       <= 1'b0;
            sign_b_s2       <= 1'b0;
            flags_a_s2      <= '0;
            flags_b_s2      <= '0;
        end else begin
            valid_stage2 <= valid_stage1;
            if (valid_stage1) begin
                exp_a_s2        <= exp_a_s1;
                exp_b_s2        <= exp_b_s1;
                max_exponent_s2 <= max_exponent_comb;
                mant_a_s2       <= mant_a_s1;
                mant_b_s2       <= mant_b_s1;
                sign_a_s2       <= sign_a_s1;
                sign_b_s2       <= sign_b_s1;
                flags_a_s2      <= flags_a_s1;
                flags_b_s2      <= flags_b_s1;
            end
        end
    end

    // 第二级组合逻辑：计算指数差值并进行对阶移位
    always_comb begin
        exp_diff_a_s2 = max_exponent_s2 - exp_a_s2;
        exp_diff_b_s2 = max_exponent_s2 - exp_b_s2;

        // 对阶移位，扩展尾数并右移
        if (exp_diff_a_s2 > ALIGNED_WIDTH - 1) begin
            aligned_mant_a_s2 = '0;
        end else begin
            aligned_mant_a_s2 = ({mant_a_s2, {RWIDTH{1'b0}}} >> exp_diff_a_s2);
        end

        if (exp_diff_b_s2 > ALIGNED_WIDTH - 1) begin
            aligned_mant_b_s2 = '0;
        end else begin
            aligned_mant_b_s2 = ({mant_b_s2, {RWIDTH{1'b0}}} >> exp_diff_b_s2);
        end
    end

    // ========== 第三级流水线寄存器 (补码转换和加法) ==========
    logic              valid_stage3;
    logic [EWIDTH-1:0] max_exponent_s3;
    logic sign_a_s3, sign_b_s3;
    special_flags_t flags_a_s3, flags_b_s3;
    logic signed [ADD_WIDTH-1:0] signed_mant_a_s3, signed_mant_b_s3;
    logic signed [ADD_WIDTH-1:0] add_result_s3;

    // 补码转换组合逻辑
    logic signed [ADD_WIDTH-1:0] signed_mant_a_comb, signed_mant_b_comb;
    always_comb begin
        logic [ADD_WIDTH-1:0] extended_mant_a, extended_mant_b;

        extended_mant_a    = {{GUARD_BITS + 1{1'b0}}, aligned_mant_a_s2};
        extended_mant_b    = {{GUARD_BITS + 1{1'b0}}, aligned_mant_b_s2};

        // 使用条件赋值简化补码转换
        signed_mant_a_comb = sign_a_s2 ? (~extended_mant_a + 1'b1) : extended_mant_a;
        signed_mant_b_comb = sign_b_s2 ? (~extended_mant_b + 1'b1) : extended_mant_b;
    end

    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            valid_stage3     <= 1'b0;
            max_exponent_s3  <= '0;
            sign_a_s3        <= 1'b0;
            sign_b_s3        <= 1'b0;
            flags_a_s3       <= '0;
            flags_b_s3       <= '0;
            signed_mant_a_s3 <= '0;
            signed_mant_b_s3 <= '0;
            add_result_s3    <= '0;
        end else begin
            valid_stage3 <= valid_stage2;
            if (valid_stage2) begin
                max_exponent_s3  <= max_exponent_s2;
                sign_a_s3        <= sign_a_s2;
                sign_b_s3        <= sign_b_s2;
                flags_a_s3       <= flags_a_s2;
                flags_b_s3       <= flags_b_s2;
                signed_mant_a_s3 <= signed_mant_a_comb;
                signed_mant_b_s3 <= signed_mant_b_comb;
                add_result_s3    <= signed_mant_a_comb + signed_mant_b_comb;
            end
        end
    end

    // ========== 第四级流水线寄存器 (规格化处理) ==========
    logic              valid_stage4;
    logic [EWIDTH-1:0] max_exponent_s4;
    special_flags_t flags_a_s4, flags_b_s4;
    logic                         result_sign_s4;
    logic [        ADD_WIDTH-1:0] abs_add_result_s4;
    logic [        LOD_WIDTH-1:0] first_one_pos_s4;
    logic                         no_ones_flag_s4;
    logic [EWIDTH+GUARD_BITS-1:0] norm_exponent_s4;
    logic [          ADD_WIDTH:0] norm_significand_s4;

    // 符号位和绝对值提取
    logic                         result_sign_comb;
    logic [        ADD_WIDTH-1:0] abs_add_result_comb;
    assign result_sign_comb    = add_result_s3[ADD_WIDTH-1];
    assign abs_add_result_comb = result_sign_comb ? (~add_result_s3 + 1) : add_result_s3;

    // LOD实例化
    logic [LOD_WIDTH-1:0] first_one_pos_comb;
    logic                 no_ones_flag_comb;

    lod #(
        .LEN(ADD_WIDTH)
    ) u_lod (
        .in_i(abs_add_result_comb),
        .first_one_o(first_one_pos_comb),
        .no_ones_o(no_ones_flag_comb)
    );

    // 规格化处理组合逻辑
    logic [           EWIDTH-1:0] leading_zeros_comb;
    logic [  EWIDTH+GUARD_BITS:0] extended_max_exp_comb;
    logic [EWIDTH+GUARD_BITS-1:0] norm_exponent_comb;
    logic [          ADD_WIDTH:0] norm_significand_comb;

    assign leading_zeros_comb = {{(EWIDTH - LOD_WIDTH) {1'b0}}, first_one_pos_comb};
    assign extended_max_exp_comb = max_exponent_s3 + GUARD_BITS + 1;
    assign norm_exponent_comb = (extended_max_exp_comb > leading_zeros_comb) ? 
                               extended_max_exp_comb - leading_zeros_comb : '0;
    assign norm_significand_comb = (leading_zeros_comb == 0) ? 
                                  abs_add_result_comb[ADD_WIDTH-1:RWIDTH] :
                                  (abs_add_result_comb << leading_zeros_comb);

    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            valid_stage4        <= 1'b0;
            max_exponent_s4     <= '0;
            flags_a_s4          <= '0;
            flags_b_s4          <= '0;
            result_sign_s4      <= 1'b0;
            abs_add_result_s4   <= '0;
            first_one_pos_s4    <= '0;
            no_ones_flag_s4     <= 1'b0;
            norm_exponent_s4    <= '0;
            norm_significand_s4 <= '0;
        end else begin
            valid_stage4 <= valid_stage3;
            if (valid_stage3) begin
                max_exponent_s4     <= max_exponent_s3;
                flags_a_s4          <= flags_a_s3;
                flags_b_s4          <= flags_b_s3;
                result_sign_s4      <= result_sign_comb;
                abs_add_result_s4   <= abs_add_result_comb;
                first_one_pos_s4    <= first_one_pos_comb;
                no_ones_flag_s4     <= no_ones_flag_comb;
                norm_exponent_s4    <= norm_exponent_comb;
                norm_significand_s4 <= norm_significand_comb;
            end
        end
    end

    // ========== 第五级流水线寄存器 (舍入和最终结果) ==========
    logic guard_s4, round_s4, sticky_s4;
    logic                         round_up_s4;
    logic [           MWIDTH-1:0] final_mantissa_s4;
    logic [EWIDTH+GUARD_BITS-1:0] adjusted_exponent_s4;

    // IEEE 754最近偶数舍入
    assign guard_s4    = norm_significand_s4[RWIDTH+1];
    assign round_s4    = norm_significand_s4[RWIDTH];
    assign sticky_s4   = |norm_significand_s4[RWIDTH-1:0];
    assign round_up_s4 = guard_s4 & (round_s4 | sticky_s4 | norm_significand_s4[RWIDTH+2]);

    logic [SIGNIFICAND_WIDTH:0] mantissa_before_round_s4;
    logic [SIGNIFICAND_WIDTH:0] mantissa_after_round_s4;

    assign mantissa_before_round_s4 = {1'b0, norm_significand_s4[ADD_WIDTH:ADD_WIDTH-SIGNIFICAND_WIDTH]};
    assign mantissa_after_round_s4  = mantissa_before_round_s4 + round_up_s4;
    assign final_mantissa_s4        = mantissa_after_round_s4[MWIDTH-1:0];
    assign adjusted_exponent_s4     = norm_exponent_s4 + mantissa_after_round_s4[SIGNIFICAND_WIDTH];

    // 异常处理
    logic exponent_overflow_s4, exponent_underflow_s4;
    logic any_inf_s4, any_nan_s4;
    assign exponent_overflow_s4  = (adjusted_exponent_s4 >= MAX_EXP);
    assign exponent_underflow_s4 = (adjusted_exponent_s4 == 0);
    assign any_inf_s4            = flags_a_s4.is_inf | flags_b_s4.is_inf;
    assign any_nan_s4            = flags_a_s4.is_nan | flags_b_s4.is_nan;

    // 最终结果组装
    logic result_is_zero_s4;
    assign result_is_zero_s4 = no_ones_flag_s4 | (~|abs_add_result_s4);

    logic [EWIDTH-1:0] final_exponent_s4;
    logic [MWIDTH-1:0] final_mantissa_processed_s4;

    assign final_exponent_s4 = exponent_underflow_s4 ? EXP_ZEROS : adjusted_exponent_s4[EWIDTH-1:0];
    assign final_mantissa_processed_s4 = exponent_underflow_s4 ? 
                                        (mantissa_after_round_s4 >> (first_one_pos_s4 - GUARD_BITS - 1)) :
                                        final_mantissa_s4;

    // 特殊情况处理
    logic              inf_nan_result_s4;
    logic [DWIDTH-1:0] inf_nan_value_s4;

    assign inf_nan_result_s4 = any_nan_s4 | any_inf_s4;

    always_comb begin
        if (any_nan_s4) begin
            inf_nan_value_s4 = NAN;
        end else if (flags_a_s4.is_inf & flags_b_s4.is_inf & (result_sign_s4)) begin
            inf_nan_value_s4 = NAN;
        end else if (flags_a_s4.is_inf) begin
            inf_nan_value_s4 = {flags_a_s4.is_inf ? result_sign_s4 : 1'b0, EXP_ONES, MANT_ZEROS};
        end else if (flags_b_s4.is_inf) begin
            inf_nan_value_s4 = {flags_b_s4.is_inf ? result_sign_s4 : 1'b0, EXP_ONES, MANT_ZEROS};
        end else begin
            inf_nan_value_s4 = NAN;
        end
    end

    // 输出寄存器
    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            valid_out <= 1'b0;
            result    <= '0;
            exception <= 1'b0;
        end else begin
            valid_out <= valid_stage4;
            if (valid_stage4) begin
                if (inf_nan_result_s4) begin
                    result <= inf_nan_value_s4;
                end else if (result_is_zero_s4) begin
                    if (flags_a_s4.is_zero & flags_b_s4.is_zero & result_sign_s4) begin
                        result <= 32'h80000000;  // -0.0
                    end else begin
                        result <= 32'h00000000;  // +0.0
                    end
                end else if (exponent_overflow_s4) begin
                    result <= {result_sign_s4, EXP_ONES, MANT_ZEROS};
                end else begin
                    result <= {result_sign_s4, final_exponent_s4, final_mantissa_processed_s4};
                end

                exception <= any_inf_s4 | any_nan_s4 | exponent_overflow_s4;
            end
        end
    end

endmodule
